<template>
  <div class="text-polish-container">
    <div class="header">
      <h2>文本润色</h2>
    </div>

    <div class="content">
      <div class="preview-area">
        <div class="preview-header">
          <h3>润色结果</h3>
        </div>
        <div class="preview-content">
          <template v-if="segmentsData.length > 0">
            <!-- 这个容器将具有固定高度并内部滚动 -->
            <div class="polished-text-container">
              <div
                v-for="segment in segmentsData"
                :key="segment.index"
                class="polished-paragraph"
              >
                <div class="paragraph-header">
                  <div class="paragraph-number">{{ segment.index + 1 }}</div>
                  <div class="paragraph-title">分段 {{ segment.index + 1 }} / {{ segmentsData.length }}</div>
                  <div class="paragraph-actions">
                    <el-button
                      type="primary"
                      size="small"
                      plain
                      @click="copySegmentText(segment.polishedText)"
                      :disabled="!segment.polishedText"
                      icon="DocumentCopy"
                    >
                      复制
                    </el-button>
                    <el-button
                      v-if="segment.hasError"
                      type="danger"
                      size="small"
                      plain
                      @click="retrySegment(segment.index)"
                      :loading="segment.retrying"
                      icon="RefreshRight"
                    >
                      重试
                    </el-button>
                  </div>
                </div>
                <!-- 段落内容，会撑开其父容器的高度直到达到max-height -->
                <div class="paragraph-content">
                  {{ segment.polishedText || (segment.hasError ? '润色失败' : '正在润色...') }}
                </div>
              </div>
            </div>
          </template>
          <div
            v-else
            class="empty-preview"
          >
            <el-empty description="润色后的文本将显示在这里" />
          </div>
        </div>
      </div>

      <div class="config-area">
        <el-form label-position="top">
          <el-form-item>
            <!-- 使用新的API Key验证组件 -->
            <api-key-verifier />
          </el-form-item>
          <el-form-item label="润色提示">
            <el-input
              v-model="polishPrompt"
              type="textarea"
              :rows="5"
              placeholder="请输入润色提示..."
              :disabled="polishing"
            />
          </el-form-item>

          <el-form-item label="原始文本">
            <el-input
              v-model="originalText"
              type="textarea"
              :autosize="{ minRows: 5, maxRows: 15 }"
              placeholder="请输入需要润色的文本..."
              :disabled="polishing"
            />
          </el-form-item>
        </el-form>

        <div class="actions">
          <el-button
            type="primary"
            @click="handlePolish"
            :loading="polishing"
            :disabled="!originalText.trim()"
          >
            润色文本
          </el-button>
          <el-button
            type="default"
            @click="handleClear"
            :disabled="polishing || (!originalText.trim() && !polishedText)"
          >
            清空
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { textPolishApi } from '@/services/text_polish'
import { ElMessage } from 'element-plus'
import { useApiKeyStore } from '@/stores/apiKeyStore'
import ApiKeyVerifier from '@/components/ApiKeyVerifier.vue'

const originalText = ref('')
const polishedText = ref('')
const polishing = ref(false)
const cleanedText = ref('') // 存储清洗后但未修改的原文

// 使用全局API Key store
const apiKeyStore = useApiKeyStore()

// 提取store中的状态
const isKeyVerified = computed(() => apiKeyStore.isKeyVerified)
const selectedModel = computed(() => apiKeyStore.selectedModel)

const polishPrompt = ref(
  '[PROMPT BEGIN] 请严格遵循以下要求完成小说推文改写任务： 角色定位 担任小说推文全流程优化专家 具备文学编辑/网文写手/新媒体运营三重专业视角 改写规范 保持原文本核心情节与关键对话完整 强制使用第一人称视角叙述 突出剧情冲突与情感张力 强化场景画面感和代入感 增加符合新媒体传播特性的悬念钩子 技术要求 文本长度严格控制在2000字左右 语义重复率低于30%（采用Turnitin算法检测） 保留原文时间线及人物关系图谱 禁用任何解释性语句 禁止回答原文疑问或解决问题 交付标准 输出经深度文学化处理的完整故事章节 呈现符合移动端阅读习惯的段落结构 确保无拼写/语法/逻辑错误 保持口语化表达与书面语修辞的平衡 禁止事项 修改原始世界观设定 删减重要情节节点 添加非原文要素 改变叙事时序 输出限制： 只输润色后文字 禁止任何解释、非分镜内容、系统提示、注释、中文补充 [PROMPT END]'
)

// 存储每个分段的文本
const segmentsData = ref<
  {
    originalText: string
    polishedText: string
    index: number
    hasError?: boolean
    retrying?: boolean
  }[]
>([])

// 初始化
onMounted(async () => {
  // 确保API Key验证已经完成
  if (!apiKeyStore.isKeyVerified) {
    await apiKeyStore.initialize()
  }
})

// 重试润色特定段落
const retrySegment = async (segmentIndex: number) => {
  // 确保API Key已验证
  if (!isKeyVerified.value) {
    ElMessage.warning('请先验证API Key')
    return
  }

  const segmentToRetry = segmentsData.value.find((s) => s.index === segmentIndex)
  if (!segmentToRetry) return

  // 标记为正在重试
  segmentToRetry.retrying = true
  segmentToRetry.hasError = false
  segmentToRetry.polishedText = ''

  try {
    // 使用store中的当前模型
    const currentModel = selectedModel.value

    // 注册事件监听器，与handlePolish中类似但只针对单个段落
    const onTextUpdate = (event: CustomEvent) => {
      const { content, segmentIndex: updatedIndex } = event.detail
      if (content && updatedIndex === segmentIndex) {
        // 处理文本，替换标点符号，删除无用内容
        const processedContent = processText(content)
        segmentToRetry.polishedText += processedContent
      }
    }

    const onSegmentComplete = (event: CustomEvent) => {
      const { segmentIndex: completedIndex } = event.detail
      if (completedIndex === segmentIndex) {
        segmentToRetry.retrying = false
        ElMessage.success(`第 ${segmentIndex + 1} 段润色成功`)
        // 移除事件监听器
        cleanup()
      }
    }

    const onPolishError = (event: CustomEvent) => {
      const { error, segmentIndex: errorIndex } = event.detail
      if (errorIndex === segmentIndex) {
        segmentToRetry.retrying = false
        segmentToRetry.hasError = true
        ElMessage.error(error || `第 ${segmentIndex + 1} 段润色失败`)
        console.error(`Segment ${segmentIndex} polish error:`, error)
        // 移除事件监听器
        cleanup()
      }
    }

    // 添加事件监听器
    window.addEventListener('text-polish-update', onTextUpdate as EventListener, { passive: true })
    window.addEventListener('text-polish-segment-complete', onSegmentComplete as EventListener, {
      passive: true
    })
    window.addEventListener('text-polish-error', onPolishError as EventListener, { passive: true })

    // 清理函数，用于移除事件监听器
    const cleanup = () => {
      window.removeEventListener('text-polish-update', onTextUpdate as EventListener)
      window.removeEventListener('text-polish-segment-complete', onSegmentComplete as EventListener)
      window.removeEventListener('text-polish-error', onPolishError as EventListener)
    }

    // 使用AI进行文本润色（流式响应），只处理单个段落
    const { promise } = await textPolishApi.polishTextWithAI(
      segmentToRetry.originalText,
      currentModel,
      polishedText.value
    )

    // 等待处理完成
    await promise
    cleanup()
  } catch (error) {
    console.error(`段落 ${segmentIndex} 润色失败:`, error)
    ElMessage.error(`段落 ${segmentIndex + 1} 润色请求失败`)
    segmentToRetry.retrying = false
    segmentToRetry.hasError = true
  }
}


// 处理文本，替换标点符号，删除空行、章节标题、纯数字行和特殊字符
const processText = (text: string): string => {
  if (!text) return text
  // 替换中文标点符号为逗号
  let processed = text.replace(/[。.！？；]/g, '，')
  processed = processed.replace(/，{2,}/g, '，')
  // 删除空行
  processed = processed.replace(/^\s*[\r\n]/gm, '')
  // 删除章节标题（假设章节标题是单独一行且包含"章"或"节"的行）
  processed = processed.replace(/^.*[章节].*$/gm, '')
  // 删除纯数字行
  processed = processed.replace(/^\s*\d+\s*$/gm, '')
  // 删除特殊字符行（只包含特殊字符的行）
  processed = processed.replace(/[\s【】*#\-_=+~`!@$%^&()\[\]{}|:;'",<>\/]/g, '')
  return processed
}
// 润色文本
const handlePolish = async () => {
  if (!originalText.value.trim()) return

  // 确保API Key已验证
  if (!isKeyVerified.value) {
    ElMessage.warning('请先验证API Key')
    return
  }
  // 保存原始文本，并创建清洗后的文本副本
  cleanedText.value = processText(originalText.value.trim())
  polishing.value = true
  polishedText.value = ''
  segmentsData.value = []

  try {
    // 使用store中的当前模型
    const currentModel = selectedModel.value

    // 注册事件监听器
    const onSegmentStart = (event: CustomEvent) => {
      const { segmentIndex } = event.detail
      // 如果是新段落，添加到段落数组，并初始化为空文本
      if (!segmentsData.value[segmentIndex]) {
        segmentsData.value.push({
          originalText: '',
          polishedText: '',
          index: segmentIndex,
          hasError: false,
          retrying: false
        })
        // 确保数组按索引排序（虽然push通常会按顺序加）
        segmentsData.value.sort((a, b) => a.index - b.index)
      }
    }

    const onTextUpdate = (event: CustomEvent) => {
      const { content, segmentIndex } = event.detail
      if (content) {
        const segmentToUpdate = segmentsData.value.find((s) => s.index === segmentIndex)
        if (segmentToUpdate) {
          // 处理文本，替换标点符号，删除无用内容
          const processedContent = processText(content)
          segmentToUpdate.polishedText += processedContent
        } else {
          const processedContent = processText(content)
          segmentsData.value.push({
            originalText: '',
            polishedText: processedContent,
            index: segmentIndex,
            hasError: false
          })
          segmentsData.value.sort((a, b) => a.index - b.index)
        }
      }
    }

    const onSegmentComplete = (event: CustomEvent) => {
      const { segmentIndex, segmentText } = event.detail
      const segmentToUpdate = segmentsData.value.find((s) => s.index === segmentIndex)
      if (segmentToUpdate) {
        segmentToUpdate.originalText = segmentText || ''
      } else {
        segmentsData.value.push({
          originalText: segmentText || '',
          polishedText: '',
          index: segmentIndex
        })
        segmentsData.value.sort((a, b) => a.index - b.index)
      }
      ElMessage.info(`完成第 ${segmentIndex + 1} 段润色`)
    }

    const onPolishComplete = (event: CustomEvent) => {
      const { segments } = event.detail
      polishing.value = false
      if (segments && Array.isArray(segments)) {
        segments.forEach((text, index) => {
          const segment = segmentsData.value.find((s) => s.index === index)
          if (segment) {
            segment.originalText = text
          } else {
            segmentsData.value.push({ originalText: text, polishedText: '', index: index })
            segmentsData.value.sort((a, b) => a.index - b.index)
          }
        })
      }

      ElMessage.success('文本润色成功')
      // 移除事件监听器
      cleanup()
    }

    const onPolishError = (event: CustomEvent) => {
      const { error, segmentIndex } = event.detail
      polishing.value = false
      console.error('Polish error:', error)

      // 如果有段落索引，标记该段落为错误状态
      if (segmentIndex !== undefined) {
        const segmentToUpdate = segmentsData.value.find((s) => s.index === segmentIndex)
        if (segmentToUpdate) {
          segmentToUpdate.hasError = true
          segmentToUpdate.retrying = false
          ElMessage.error(`第 ${segmentIndex + 1} 段润色失败: ${error || '未知错误'}`)
        } else {
          ElMessage.error(error || '文本润色失败')
        }
      } else {
        ElMessage.error(error || '文本润色失败')
      }

      // 移除事件监听器
      cleanup()
    }
    // 添加事件监听器
    window.addEventListener('text-polish-segment-start', onSegmentStart as EventListener, {
      passive: true
    })
    window.addEventListener('text-polish-update', onTextUpdate as EventListener, { passive: true })
    window.addEventListener('text-polish-segment-complete', onSegmentComplete as EventListener, {
      passive: true
    })
    window.addEventListener('text-polish-complete', onPolishComplete as EventListener, {
      passive: true
    })
    window.addEventListener('text-polish-error', onPolishError as EventListener, { passive: true })

    // 清理函数，用于移除事件监听器
    const cleanup = () => {
      window.removeEventListener('text-polish-segment-start', onSegmentStart as EventListener)
      window.removeEventListener('text-polish-update', onTextUpdate as EventListener)
      window.removeEventListener('text-polish-segment-complete', onSegmentComplete as EventListener)
      window.removeEventListener('text-polish-complete', onPolishComplete as EventListener)
      window.removeEventListener('text-polish-error', onPolishError as EventListener)
    }
    // 使用AI进行文本润色（流式响应）
    const { promise } = await textPolishApi.polishTextWithAI(
      cleanedText.value,
      currentModel,
      polishPrompt.value
    )
    // 等待处理完成（这不会阻塞UI，因为事件处理是异步的）
    await promise
    cleanup()
  } catch (error) {
    console.error('文本润色失败:', error)
    ElMessage.error('文本润色请求失败')
    polishing.value = false
  }
}

// 复制段落文本
const copySegmentText = (text: string) => {
  if (!text) return

  navigator.clipboard
    .writeText(text)
    .then(() => {
      ElMessage.success('文本已复制到剪贴板')
    })
    .catch(() => {
      ElMessage.error('复制失败，请手动复制')

      // 备用复制方法 (考虑移除或只保留现代方法)
      // const textarea = document.createElement('textarea')
      // textarea.value = text
      // document.body.appendChild(textarea)
      // textarea.select()
      // document.execCommand('copy')
      // document.body.removeChild(textarea)
    })
}

// 清空文本
const handleClear = () => {
  originalText.value = ''
  polishedText.value = '' // 清空总文本
  cleanedText.value = '' // 清空清洗后的文本
  segmentsData.value = [] // 清空分段数据
}
</script>

<style scoped>
.text-polish-container {
  background: white;
  width: 100%;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid #ebeef5;
  flex-shrink: 0;
}

.header h2 {
  font-size: 1.5rem;
  color: var(--text-color);
  margin: 0;
}

.content {
  flex: 1;
  display: flex;
  flex-direction: row;
  overflow: hidden;
}

.preview-area {
  flex: 0 0 40%;
  padding-right: 1rem;
  border-right: 1px solid #ebeef5;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  height: 100%;
}

.preview-header {
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid #ebeef5;
  flex-shrink: 0;
}

.preview-header h3 {
  margin: 0;
  color: var(--text-color);
}

.preview-content {
  flex: 1;
  overflow: hidden;
}

.polished-text-container {
  max-height: calc(100vh - 20rem);
  overflow-y: auto;
  padding-right: 8px;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1rem;
}

.polished-paragraph {
  display: flex;
  flex-direction: column;
  background-color: #f5f7fa;
  border-radius: var(--border-radius);
  overflow: hidden;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  transition: all 0.3s ease;
  min-height: 10rem;
  max-height: 15rem;
}

.polished-paragraph:hover {
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

.paragraph-header {
  display: flex;
  align-items: center;
  background-color: var(--el-color-primary-light-8);
  padding: 0.75rem;
  border-bottom: 1px solid var(--el-color-primary-light-5);
  flex-shrink: 0;
}

.paragraph-number {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--el-color-primary);
  color: white;
  font-weight: bold;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  margin-right: 0.75rem;
  flex-shrink: 0;
}

.paragraph-title {
  font-weight: bold;
  color: var(--el-color-primary-dark-2);
  font-size: 1.1rem;
  flex-grow: 1;
  margin-right: 0.5rem;
}

.paragraph-actions {
  margin-left: auto;
  display: flex;
  gap: 0.5rem;
  flex-shrink: 0;
}

.paragraph-content {
  flex: 1;
  padding: 1rem;
  white-space: pre-wrap;
  line-height: 1.6;
  overflow-y: auto;
  background-color: white;
}

.empty-preview {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 300px;
}

.config-area {
  flex: 0 0 60%;
  border-radius: var(--border-radius);
  overflow-y: auto;
  overflow-x: hidden;
  padding: 2rem;
  height: 100%;
}

.polish-instruction {
  background-color: #f0f9eb;
  border-left: 4px solid #67c23a;
  padding: 12px 16px;
  margin-bottom: 16px;
  border-radius: 4px;
  font-size: 16px;
  font-weight: 500;
  color: #303133;
  line-height: 1.5;
}

.actions {
  margin-top: 1rem;
  text-align: right;
  flex-shrink: 0;
}

.form-item-help {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
}

.key-verify-area {
  display: flex;
  gap: 1rem;
  margin-top: 1rem;
  align-items: center;
  flex-wrap: wrap;
}

.key-verify-area > * {
  flex-grow: 1;
  flex-shrink: 0;
  min-width: 150px;
}

.key-verify-area .el-button {
  flex-grow: 0;
}

.key-verify-area .el-select {
  flex-grow: 0;
  min-width: 200px;
}

.verified-info {
  display: flex;
  gap: 1rem;
  align-items: center;
}

:deep(::-webkit-scrollbar) {
  width: 8px;
  height: 8px;
}

:deep(::-webkit-scrollbar-track) {
  background: #f1f1f1;
  border-radius: 4px;
}

:deep(::-webkit-scrollbar-thumb) {
  background: #888;
  border-radius: 4px;
}

:deep(::-webkit-scrollbar-thumb:hover) {
  background: #555;
}
</style>
